﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Possan.Localization.Scanner
{
	public class CSharpTokenizer
	{
		public string Source { get; set; }

		private int position;

		public CSharpTokenizer()
		{
			position = 0;
		}

		public CSharpTokenizer(string line)
			: this()
		{
			Source = line;
		}

		public bool EndOfString
		{
			get
			{
				return (position >= Source.Length);
			}
		}

		public string PeekText(char extrastop)
		{
			string output = "";
			int tempposition = position;
			bool keeprunning;
			do
			{
				keeprunning = false;
				char ch = '\n';
				if (tempposition < Source.Length)
					ch = Source[tempposition];
				if (extrastop == '\0')
				{
					if (!IsWhitespace(ch))
					{
						output += ch;
						tempposition++;
						keeprunning = true;
					}
				}
				else
				{
					if (ch != extrastop)
					{
						output += ch;
						tempposition++;
						keeprunning = true;
					}
				}
			}
			while (keeprunning);
			return output;
		}

		public string ReadText(char extrastop)
		{
			string output = "";
			bool keeprunning;
			do
			{
				keeprunning = false;
				if (position < Source.Length)
				{
					char ch = Source[position];
					if (extrastop == '\0')
					{
						if (!IsWhitespace(ch))
						{
							output += ch;
							position++;
							keeprunning = true;
						}
					}
					else
					{
						if (ch != extrastop)
						{
							output += ch;
							position++;
							keeprunning = true;
						}
					}
				}
			}
			while (keeprunning);
			return output;
		}

		public string ReadText()
		{
			return ReadText('\0');
		}


		public bool PeekChar(char ch)
		{
			if (position < Source.Length)
				if (Source[position] == ch)
					return true;
			return true;
		}

		public bool ReadChar(char ch)
		{
			if (position < Source.Length)
			{
				if (Source[position] == ch)
				{
					position++;
					return true;
				}
				position++;
			}
			return false;
		}

		bool IsWhitespace(char ch)
		{
			return (ch == ' ' || ch == '\n' || ch == '\t' || ch == '\r' || ch == '\b');
		}

		public bool SkipWhitespace()
		{
			return SkipWhitespace('\0');
		}

		public bool SkipWhitespace(char extrawhitespace)
		{
			bool keeprunning;

			do
			{
				keeprunning = false;
				if (position < Source.Length)
				{
					char ch = Source[position];
					if (IsWhitespace(ch) || (extrawhitespace != '\0' && ch == extrawhitespace))
					{
						position++;
						keeprunning = true;
					}
				}
			}
			while (keeprunning);

			return true;
		}




		public string ReadCSharpStringValue()
		{
			string output = "";

			bool is_multiline = false;
			bool in_outerquotes = false;

			bool keeprunning;
			do
			{
				keeprunning = false;
				if (position < Source.Length)
				{
					char ch = Source[position];
					position++;

					char nextchar = '\0';
					if( position  < Source.Length )
						nextchar = Source[position];

					if (!in_outerquotes)
					{
						if (ch == '@')
						{
							// hoppa över \"
							// nextchar måste vara == '\"'
							position++;
							is_multiline = true;
							in_outerquotes = true;
							keeprunning = true;
						}
						else if (ch == '\"')
						{
							in_outerquotes = true;
							keeprunning = true;
						}
					}
					else
					{
						if (ch == '\\')
						{
							if (position + 1 < Source.Length)
							{
								position++;

								switch( nextchar )
								{
									case 'n':
										output += '\n';
										break;
									case 'b':
										output += '\b';
										break;
									case 't':
										output += '\t';
										break;
									case 'r':
										output += '\r';
										break;
									default:
										output += nextchar;
										break;
								}

								keeprunning = true;
							}
						}
						else if (ch == '\"')
						{
							if (is_multiline)
							{
								// found quote, peek next char
								if (nextchar == '\"')
								{
									// just an escaped string...
									output += "\"";
									position++;
									keeprunning = true;
								}
							}
							else
							{
								in_outerquotes = false;
							}
						}
						else
						{
							output += ch;
							keeprunning = true;
						}
					}
				}
			} while (keeprunning);


			return output;
		}



	}
}
